h2. Prototyping Forms with Formtastic

Rails allows for quick and easy creation of application prototypes and Formtastic makes prototyping an even easier and quicker process.

This four line Formtastic code block produces a form for an example database of books. 

<pre>
  <% semantic_form_for @book do |form| %>
    <%= form.inputs %>
    <%= form.buttons %>
  <% end %>
</pre>

The example book database assumes the following:

* A book belongs to one publisher (belongs_to association).
* A publisher has many books that they've published (has_many association).
* A book can have one or more authors and an author can have written one or more books - a has_and_belongs_to_many (habtm) association that is mediated by the intermediate join table authors_books.
* a book can come in many format types and a format type can exist for many books - another habtm association mediated by the join table books_format_types.

The Formtastic code block shown above in combination with these Rails "partial, views, models and tables":http://wiki.github.com/justinfrench/formtastic/7-example-code  renders this "HTML":http://wiki.github.com/justinfrench/formtastic/8-example-rendered-html output. 

h4. Points Worth Noting

Points to note about the rendered HTML:

* Most of the book model attributes are rendered into HTML, including the book belongs_to association with its parent model publisher (as a drop down select input of pubhishers names). Attributes *not* rendered by the above Formtastic code block are:
** Any multi-select habtm relationship. However, by applying a small change to the Formtastic code (shown below), they can be included in the output.
** The created_at and updated_at dates are not output as a matter of convention - again they can be output by the code block listed below:
* As is the case with Rails, Formtastic uses "convention over configuration" to make the efficiency gains it does. In the case of has_many and habtm associations Formtastic looks for specific column names in the has_many and habtm tables that are used to populate the selects and multi-selects
** Those attribute names are: to_label, display_name, full_name, name, title, username, login and value
** This convention can be overidden by using the input option :label_method. If the publisher model used @publisher_name@ instead of @:name@ the select of publishers' names, to be populated correctly, would require this input option @:label_method => :publisher name@ . See "Formastic Options" for further details. 
* Finally - in the migration file for the join tables - the primary id has been suppressed using  :id => false

h4. How to Include HABTM Associations in the Rendered Output

By explicitly listing the attributes to be rendered, the habtm attributes (authors and format_types)  will be included as multi-select input fields. 

<pre>
<% semantic_form_for @book do |form| %>
    <%= form.inputs :title, :description, :publisher, :still_in_print, :published,
                    :isbn_number, :price, :authors, :format_types, :created_at, :updated_at %>
    <%= form.buttons :commit %>
  <% end %>
</pre>

Passing attribute names to the form.inputs method has more than one purpose. As well as allowing for the inclusion of habtm attributes, they also can be used to limit the number of inputs rendered and in what order they are displayed in the rendered form simply based on the attributes included and the order in which they are included.